/**
 * Created by PanJiaChen on 16/11/18.
 */

/**
 * Parse the time to string
 * @param {(Object|string|number)} time
 * @param {string} cFormat
 * @returns {string | null}
 */
export function parseTime (time, cFormat) {
  if (arguments.length === 0 || !time) {
    return null
  }
  const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}'
  let date
  if (typeof time === 'object') {
    date = time
  } else {
    if (typeof time === 'string') {
      if (/^[0-9]+$/.test(time)) {
        // support "1548221490638"
        time = parseInt(time)
      } else {
        // support safari
        // https://stackoverflow.com/questions/4310953/invalid-date-in-safari
        time = time.replace(new RegExp(/-/gm), '/')
      }
    }

    if (typeof time === 'number' && time.toString().length === 10) {
      time = time * 1000
    }
    date = new Date(time)
  }
  const formatObj = {
    y: date.getFullYear(),
    m: date.getMonth() + 1,
    d: date.getDate(),
    h: date.getHours(),
    i: date.getMinutes(),
    s: date.getSeconds(),
    a: date.getDay()
  }
  const time_str = format.replace(/{([ymdhisa])+}/g, (result, key) => {
    const value = formatObj[key]
    // Note: getDay() returns 0 on Sunday
    if (key === 'a') {
      return ['日', '一', '二', '三', '四', '五', '六'][value]
    }
    return value.toString().padStart(2, '0')
  })
  return time_str
}

/**
 * @param {number} time
 * @param {string} option
 * @returns {string}
 */
export function formatTime (time, option) {
  if (('' + time).length === 10) {
    time = parseInt(time) * 1000
  } else {
    time = +time
  }
  const d = new Date(time)
  const now = Date.now()

  const diff = (now - d) / 1000

  if (diff < 30) {
    return '刚刚'
  } else if (diff < 3600) {
    // less 1 hour
    return Math.ceil(diff / 60) + '分钟前'
  } else if (diff < 3600 * 24) {
    return Math.ceil(diff / 3600) + '小时前'
  } else if (diff < 3600 * 24 * 2) {
    return '1天前'
  }
  if (option) {
    return parseTime(time, option)
  } else {
    return (
      d.getMonth() +
      1 +
      '月' +
      d.getDate() +
      '日' +
      d.getHours() +
      '时' +
      d.getMinutes() +
      '分'
    )
  }
}

/**
 * @description url路径的参数转成对象
 * @param {string} url
 * @returns {object}
 */
export function param2Obj (url) {
  const search = decodeURIComponent(url.split('?')[1]).replace(/\+/g, ' ')
  if (!search) {
    return {}
  }
  const obj = {}
  const searchArr = search.split('&')
  searchArr.forEach(v => {
    const index = v.indexOf('=')
    if (index !== -1) {
      const name = v.substring(0, index)
      const val = v.substring(index + 1, v.length)
      obj[name] = val
    }
  })
  return obj
}

/**
 * @description 对象转化为formdata
 * @param {Object} data
 * @returns {FormData}
 */

// export function fd (data) {
//   // 检查data是否已经是FormData实例
//   if (data instanceof FormData) {
//     return data;
//   }

//   let obj = JSON.parse(JSON.stringify(data));
//   let fd = new FormData();
//   let arr = Object.keys(obj);
//   arr.forEach(item => {
//     if (obj[item] === null) obj[item] = '';
//     if (obj[item].constructor === Object) {
//       // 嵌套了对象
//       Object.keys(obj[item]).forEach(subValue =>
//         fd.append(item + `.${subValue}`, obj[item][subValue])
//       );
//     } else {
//       fd.append(`${item}`, obj[item]);
//     }
//   });
//   return fd;
// }

// export function fd (data) {
//   if (data instanceof FormData) return data;

//   const processValue = (fd, key, value) => {
//     if (value === null || value === undefined) {
//       fd.append(key, '');
//     } else if (Array.isArray(value)) {
//       value.forEach((item, index) => {
//         if (typeof item === 'object') {
//           Object.keys(item).forEach(subKey =>
//             fd.append(`${key}[${index}].${subKey}`, item[subKey])
//           );
//         } else {
//           fd.append(`${key}[${index}]`, item);
//         }
//       });
//     } else if (typeof value === 'object') {
//       Object.keys(value).forEach(subKey =>
//         fd.append(`${key}.${subKey}`, value[subKey])
//       );
//     } else {
//       fd.append(key, value);
//     }
//   };

//   const fd = new FormData();
//   const obj = JSON.parse(JSON.stringify(data));
//   Object.keys(obj).forEach(key => processValue(fd, key, obj[key]));
//   return fd;
// }

// export function fd (data) {
//   if (data instanceof FormData) return data;

//   const processValue = (fd, key, value) => {
//     if (value === null || value === undefined) {
//       fd.append(key, '');
//     } else if (Array.isArray(value)) {
//       value.forEach((item, index) => {
//         if (typeof item === 'object') {
//           Object.keys(item).forEach(subKey => {
//             processValue(fd, `${key}[${index}].${subKey}`, item[subKey]);
//           });
//         } else {
//           fd.append(`${key}[${index}]`, item);
//         }
//       });
//     } else if (typeof value === 'object') {
//       Object.keys(value).forEach(subKey => {
//         processValue(fd, `${key}.${subKey}`, value[subKey]);
//       });
//     } else {
//       fd.append(key, value);
//     }
//   };

//   const fd = new FormData();
//   const obj = JSON.parse(JSON.stringify(data));
//   Object.keys(obj).forEach(key => processValue(fd, key, obj[key]));
//   return fd;
// }
export function fd (data) {
  if (data instanceof FormData) return data;

  // 如果 data 是一个值，直接将其作为值添加到 FormData 对象中
  if (typeof data !== 'object' || data === null) {
    const fd = new FormData();
    fd.append('value', data);
    return fd;
  }

  const processValue = (fd, key, value) => {
    if (value === null || value === undefined) {
      fd.append(key, '');
    } else if (Array.isArray(value)) {
      value.forEach((item, index) => {
        if (typeof item === 'object') {
          Object.keys(item).forEach(subKey => {
            processValue(fd, `${key}[${index}].${subKey}`, item[subKey]);
          });
        } else {
          fd.append(`${key}[${index}]`, item);
        }
      });
    } else if (typeof value === 'object') {
      Object.keys(value).forEach(subKey => {
        processValue(fd, `${key}.${subKey}`, value[subKey]);
      });
    } else {
      fd.append(key, value);
    }
  };

  const fd = new FormData();
  const obj = JSON.parse(JSON.stringify(data));
  Object.keys(obj).forEach(key => processValue(fd, key, obj[key]));
  return fd;
}





/**
 * @description 数组 转成 请求排序字符串 方法
 * @param {Array} arr
 * @returns {String}
 */
export function montageStr (arr) {
  let str = ''
  arr.forEach((item, index) => {
    str += `&sortList[${index}].sortName=${item.sortName}&sortList[${index}].sortType=${item.sortType}`
  })
  return str
}

// 定义微服务
export const microservices = {
  pmsSys: '/pms-sys',
  pmsFs: '/pms-fs',
  pmsSms: '/pms-sms',
  pcpesIs: '/pcpes-is',
}

// 系统编码
export const systemCode = 'S1'

// 如果是一位数字前面补0
export const formatNumber = n => {
  n = n.toString()
  return n[1] ? n : '0' + n
}

// 近N月 - new Date()
export const getRecentMonth = n => {
  let result = {}
  const datenow = new Date()
  // 当前时间
  const dateend = [
    datenow.getFullYear(),
    datenow.getMonth() + 1,
    datenow.getDate()
  ]
    .map(formatNumber)
    .join('-')
  datenow.setMonth(datenow.getMonth() - n)
  let dyear = datenow.getFullYear()
  let dmonth = datenow.getMonth() + 1
  dmonth = dmonth < 10 ? 0 + dmonth : dmonth
  let dday = datenow.getDate()
  // 往前推的时间
  const datestart = [dyear, dmonth, dday].map(formatNumber).join('-')
  result = {
    datestart,
    dateend
  }
  return result
}

/**
 * @description 秒数转天时分
 * @param {string} time 需要转换的秒数
 * @returns {string}
 */
export const MMtoDayHourMin = time => {
  if (time <= 0) return time
  if (time <= 60) return time + '秒'
  let miao = time % 60
  let min = Math.floor(time / 60)
  if (min < 60) {
    return min + '分' + miao + '秒'
  } else if (min < 1440) {
    let hour = parseInt((min / 60) % 24)
    let minute = parseInt(min % 60)
    return hour + '时' + minute + '分' + miao + '秒'
  }
  let day = parseInt(min / 1440)
  let hour = parseInt((min / 60) % 24)
  let minute = parseInt(min % 60)
  return day + '天' + hour + '时' + minute + '分' + miao + '秒'
}

/**
 * @function getRecentDay
 * @description 近N天：比如近7天就是前面7天至今
 * @param {number} n
 * @returns {string}
 */
export const getRecentDay = n => {
  var dd = new Date()
  dd.setDate(dd.getDate() - n) //获取n天前的日期
  var y = dd.getFullYear()
  var m = dd.getMonth() + 1 //获取当前月份的日期
  var d = dd.getDate()
  let day = [y, m, d].map(formatNumber).join('-')
  return day
}

// 两个时间范围之间所有日期，例如2023.10.01 - 2023.10.31 之间的31天日期
export const timeFrame = (start, end) => {
  let dateList = []
  var startTime = new Date(start)
  var endTime = new Date(end)
  while (endTime.getTime() - startTime.getTime() >= 0) {
    var year = startTime.getFullYear()
    var month =
      startTime.getMonth() + 1 < 10
        ? '0' + (startTime.getMonth() + 1)
        : startTime.getMonth() + 1
    var day =
      startTime.getDate().toString().length == 1
        ? '0' + startTime.getDate()
        : startTime.getDate()
    dateList.push(year + '-' + month + '-' + day)
    startTime.setDate(startTime.getDate() + 1)
  }
  return dateList
}

/**
 * @description 保留小数方法
 * @param {number} val 值
 * @param {number} decimals 保留位数
 * @returns {string}
 */
export const retainDecimals = (val, decimals) => {
  if (!val) return 0
  // 保留几位小数
  let dec = decimals ? decimals : 2
  // string型
  let strVal = String(val)
  // 值为0的情况
  if (val == 0) return val.toFixed(dec)
  if (strVal.includes('.')) {
    // 存在小数点
    let arr = strVal.split('.')
    let left = arr[0]
    let right = arr[1]
    if (right.length < dec) {
      for (let index = 0; index < dec - right.length; index++) {
        right += '0'
      }
    } else if (right.length > dec) {
      right = right.slice(0, 2)
    }
    return left + '.' + right
  } else {
    // 不存在小数点
    return val.toFixed(dec)
  }
}

/**
 * @function getSubsequentMonth
 * @description 往后的月份
 * @param {number} n 多少个月
 * @returns {object}
 */
export const getSubsequentMonth = n => {
  let result = {}
  const datenow = new Date()
  // 当前时间
  const datestart = [
    datenow.getFullYear(),
    datenow.getMonth() + 1,
    datenow.getDate()
  ]
    .map(formatNumber)
    .join('-')
  datenow.setMonth(datenow.getMonth() + n)
  datenow.setDate(datenow.getDate() - 1)
  let dyear = datenow.getFullYear()
  let dmonth = datenow.getMonth() + 1
  dmonth = dmonth < 10 ? 0 + dmonth : dmonth
  let dday = datenow.getDate()
  // 往前推的时间
  const dateend = [dyear, dmonth, dday].map(formatNumber).join('-')
  result = {
    datestart,
    dateend
  }
  return result
}

/**
 * @function guid
 * @description 返回32位uuid
 * @returns {string}
 */
export const guid = () => {
  // return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
  return 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
    // /[xy]/g 以及 c 分别代找到字符串的所有xy，c来取值
    // (Math.random() * 16) | 0 取 0 - 16 之间的随机数（不包含16，| 0 代表取整数）
    var r = (Math.random() * 16) | 0,
      v = c == 'x' ? r : (r & 0x3) | 0x8
    return v.toString(16)
  })
}

/**
 * @function generateRandomId
 * @description 返回随机 大写/小写/数字 字符
 * @param {number} length 长度，多少个
 * @param {string} type 类型，可选'lowe'小写，'lett'大写，'digit'数字
 * @returns {string}
 */
export const generateRandom = (length, type) => {
  const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
  const loweStr = 'abcdefghijklmnopqrstuvwxyz'
  const lettStr = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
  const digitStr = '0123456789'
  let result = ''
  if (type == 'lowe') {
    for (let i = 0; i < length; i++) {
      const randomIndex = Math.floor(Math.random() * loweStr.length)
      result += loweStr[randomIndex]
    }
  } else if (type == 'lett') {
    for (let i = 0; i < length; i++) {
      const randomIndex = Math.floor(Math.random() * lettStr.length)
      result += lettStr[randomIndex]
    }
  } else if (type == 'digit') {
    for (let i = 0; i < length; i++) {
      const randomIndex = Math.floor(Math.random() * digitStr.length)
      result += digitStr[randomIndex]
    }
  } else {
    for (let i = 0; i < length; i++) {
      const randomIndex = Math.floor(Math.random() * characters.length)
      result += characters[randomIndex]
    }
  }
  return result
}

/**
 * @function unique
 * @description 返回数组对象去重 的 数据
 * @param {Array} arr 未去重数据
 * @param {string} key 去重判断字段
 * @returns {Array}
 */
export const unique = (arr, key) => {
  const res = new Map()
  return arr.filter(arr => !res.has(arr[key]) && res.set(arr[key], arr[key]))
}
